package com.example.delicioushunter.view.activity;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import com.example.delicioushunter.R;
import com.example.delicioushunter.control.supportcontrol.DHSharedPreference;
import com.example.delicioushunter.control.supportcontrol.SDKUtils;
import com.samsung.android.sdk.SsdkUnsupportedException;
import com.samsung.android.sdk.pen.Spen;
import com.samsung.android.sdk.pen.SpenSettingPenInfo;
import com.samsung.android.sdk.pen.SpenSettingTextInfo;
import com.samsung.android.sdk.pen.document.SpenInvalidPasswordException;
import com.samsung.android.sdk.pen.document.SpenNoteDoc;
import com.samsung.android.sdk.pen.document.SpenObjectBase;
import com.samsung.android.sdk.pen.document.SpenObjectImage;
import com.samsung.android.sdk.pen.document.SpenObjectStroke;
import com.samsung.android.sdk.pen.document.SpenPageDoc;
import com.samsung.android.sdk.pen.document.SpenUnsupportedTypeException;
import com.samsung.android.sdk.pen.document.SpenUnsupportedVersionException;
import com.samsung.android.sdk.pen.engine.SpenSurfaceView;
import com.samsung.android.sdk.pen.recognition.SpenCreationFailureException;
import com.samsung.android.sdk.pen.recognition.SpenSignatureVerification;
import com.samsung.android.sdk.pen.recognition.SpenSignatureVerificationInfo;
import com.samsung.android.sdk.pen.recognition.SpenSignatureVerificationManager;
import com.samsung.android.sdk.pen.recognition.SpenSignatureVerification.ResultListener;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class SignatureRegistrationActivity extends Activity {

	private final int REQUEST_CODE_SELECT_IMAGE_BACKGROUND = 100;
	/**
	 * Spen Objects
	 */
	private Context mContext;
	private SpenNoteDoc mSpenNoteDoc;
	private SpenPageDoc mSpenPageDoc;
	private SpenSurfaceView mSpenSurfaceView;
	private SpenSignatureVerificationManager mSpenSignatureVerificationManager;
	private SpenSignatureVerification mSpenSignatureVerification;

	/**
	 * Views
	 */
	FrameLayout frame_container;
	RelativeLayout spenViewLayout;
	ImageView imgSave, imgClear, imgCheck, imgHelp;
	TextView txtCount;

	public int mResult = 0;
	public int mSignatureRegistrationNum = 0;
	public int mSignatureRegistrationNumMax = 3;
	private boolean isSpenFeatureEnabled = false;
	private DHSharedPreference shared;
	private String action;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mContext = this;
		setContentView(R.layout.activity_signature_registration);

		Intent intent = getIntent();
		action = intent.getExtras().getString("ACTION");
		// Find Views
		frame_container = (FrameLayout) findViewById(R.id.frame_container);
		spenViewLayout = (RelativeLayout) findViewById(R.id.spenViewLayout);
		imgSave = (ImageView) findViewById(R.id.imgSave);
		imgClear = (ImageView) findViewById(R.id.imgClear);
		imgCheck = (ImageView) findViewById(R.id.imgCheck);
		imgHelp = (ImageView) findViewById(R.id.imgHelp);
		txtCount = (TextView) findViewById(R.id.txtCount);
		if (action.equalsIgnoreCase("Authentication")) {
			imgSave.setVisibility(View.GONE);
			txtCount.setVisibility(View.GONE);
		}

		// Set Action Events
		imgSave.setOnTouchListener(imgSaveTouch);
		imgClear.setOnTouchListener(imgClearTouch);
		imgCheck.setOnTouchListener(imgCheckTouch);
		imgHelp.setOnTouchListener(imgHelpTouch);

		// Check device requirements
		Spen spenPackage = new Spen();
		try {
			spenPackage.initialize(mContext);
			isSpenFeatureEnabled = spenPackage
					.isFeatureEnabled(Spen.DEVICE_PEN);
		} catch (SsdkUnsupportedException i) {
			if (SDKUtils.processUnsupportedException(this, i) == true) {
				return;
			}
		} catch (Exception i) {
			i.printStackTrace();
			finish();
		}

		shared = new DHSharedPreference(mContext);
		isSpenFeatureEnabled = shared.getIsSpenFeatureEnabled();

		// Create Spen View
		mSpenSurfaceView = new SpenSurfaceView(mContext);
		mSpenSurfaceView.setRotation(1);
		mSpenSurfaceView.setZoomable(false);
		if (mSpenSurfaceView == null) {
			Toast.makeText(mContext, "Cannot creat new SpenSurfaceView",
					Toast.LENGTH_SHORT).show();
			finish();
		}
		spenViewLayout.addView(mSpenSurfaceView);

		try {
			mSpenNoteDoc = new SpenNoteDoc(mContext, 600, 600);

		} catch (IOException e) {
			Toast.makeText(mContext, "Cannot create new NoteDoc.",
					Toast.LENGTH_SHORT).show();
			e.printStackTrace();
			finish();
		} catch (Exception e) {
			e.printStackTrace();
			finish();
		}

		// Create SpenPageDoc
		mSpenPageDoc = mSpenNoteDoc.appendPage();
		mSpenPageDoc.setBackgroundColor(Color.YELLOW);
		mSpenPageDoc.clearHistory();

		// Set SpenPageDoc to SpenSurfaceView
		mSpenSurfaceView.setPageDoc(mSpenPageDoc, true);

		if (isSpenFeatureEnabled == false) {
			mSpenSurfaceView.setToolTypeAction(SpenSurfaceView.TOOL_FINGER,
					SpenSurfaceView.ACTION_STROKE);
			Toast.makeText(
					mContext,
					"Device is not support Spen. \n "
							+ "You can draw stroke with your finger",
					Toast.LENGTH_SHORT).show();
		}

		// Set Verification
		mSpenSignatureVerificationManager = new SpenSignatureVerificationManager(
				mContext);
		List<SpenSignatureVerificationInfo> signatureVerificationList = mSpenSignatureVerificationManager
				.getInfoList();
		try {
			if (signatureVerificationList.size() > 0) {
				for (SpenSignatureVerificationInfo info : signatureVerificationList) {
					if (info.name.equalsIgnoreCase("SpenSignature")) {
						mSpenSignatureVerification = mSpenSignatureVerificationManager
								.createSignatureVerification(info);
						break;
					}
				}
			} else {
				finish();
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			Toast.makeText(mContext,
					"SpenSignatureVerificationManager class not found.",
					Toast.LENGTH_SHORT).show();
			return;
		} catch (InstantiationException e) {
			e.printStackTrace();
			Toast.makeText(
					mContext,
					"Failed to access the SpenSignatureVerificationManager constructor.",
					Toast.LENGTH_SHORT).show();
			return;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			Toast.makeText(
					mContext,
					"Failed to access the SpenSignatureVerificationManager field or method.",
					Toast.LENGTH_SHORT).show();
			return;
		} catch (SpenCreationFailureException e) {
			e.printStackTrace();
			Toast.makeText(mContext,
					"This device does not support Recognition.",
					Toast.LENGTH_SHORT).show();
			finish();
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(mContext,
					"mSpenSignatureVerificationManager engine not loaded.",
					Toast.LENGTH_SHORT).show();
			return;
		}

		mSignatureRegistrationNumMax = mSpenSignatureVerification
				.getMinimumRequiredCount();

		try {
			mSpenSignatureVerification.setResultListener(new ResultListener() {
				@Override
				public void onResult(List<SpenObjectStroke> input,
						boolean result) {
					if (result) {
						shared.setLogin(true);
						Toast.makeText(mContext, "Success!", Toast.LENGTH_SHORT)
								.show();
						finish();
					} else {
						shared.setLogin(false);
						Toast.makeText(mContext, "Failure!", Toast.LENGTH_SHORT)
								.show();
					}
					for (SpenObjectBase obj : mSpenPageDoc.getObjectList()) {
						if (obj.getType() == SpenObjectBase.TYPE_STROKE)
							mSpenPageDoc.removeObject(obj);
					}
					mSpenSurfaceView.update();
				}
			});
		} catch (IllegalStateException e) {
			e.printStackTrace();
			Toast.makeText(mContext,
					"SpenSignatureVerification is not loaded.",
					Toast.LENGTH_SHORT).show();
			return;
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(mContext,
					"SpenSignatureVerification is not loaded.",
					Toast.LENGTH_SHORT).show();
			return;
		}

		Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
				R.drawable.avatar_large);

		SpenObjectImage mObjectImage = new SpenObjectImage();
		mObjectImage.setRect(new RectF(0, 0, 600, 600), false);
		mObjectImage.setImage(bitmap);
		mSpenPageDoc.appendObject(mObjectImage);
		mSpenSurfaceView.update();
		bitmap.recycle();
		bitmap = null;
		initPenSettingInfo();

	}private void initPenSettingInfo() {
		SpenSettingPenInfo spenInfo = new SpenSettingPenInfo();
		spenInfo.color = Color.RED;
		spenInfo.size = 40;
		mSpenSurfaceView.setPenSettingInfo(spenInfo);
	}
	
	

	// OnTouchListener
	OnTouchListener imgSaveTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			closeSettingView();
			ArrayList<SpenObjectBase> strokeList = mSpenPageDoc
					.getObjectList(SpenObjectBase.TYPE_STROKE);
			if (strokeList.size() > 0) {
				ArrayList<SpenObjectStroke> list = new ArrayList<SpenObjectStroke>();
				for (int i = 0; i < strokeList.size(); i++) {
					list.add((SpenObjectStroke) strokeList.get(i));
				}

				try {
					mSpenSignatureVerification.register(list);
				} catch (IllegalStateException e) {
					e.printStackTrace();
					Toast.makeText(mContext,
							"SpenSignatureVerification is not loaded.",
							Toast.LENGTH_SHORT).show();
					for (SpenObjectBase obj : mSpenPageDoc.getObjectList()) {
						if (obj.getType() == SpenObjectBase.TYPE_STROKE)
							mSpenPageDoc.removeObject(obj);
					}
					mSpenSurfaceView.update();
					return false;
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
					Toast.makeText(mContext, "SpenObjectStroke list is null.",
							Toast.LENGTH_SHORT).show();
					for (SpenObjectBase obj : mSpenPageDoc.getObjectList()) {
						if (obj.getType() == SpenObjectBase.TYPE_STROKE)
							mSpenPageDoc.removeObject(obj);
					}
					mSpenSurfaceView.update();
					return false;
				} catch (Exception e) {
					e.printStackTrace();
					Toast.makeText(
							mContext,
							"This signature is invalid for registration\n"
									+ "Please try again!", Toast.LENGTH_SHORT)
							.show();
					for (SpenObjectBase obj : mSpenPageDoc.getObjectList()) {
						if (obj.getType() == SpenObjectBase.TYPE_STROKE)
							mSpenPageDoc.removeObject(obj);
					}
					mSpenSurfaceView.update();
					return false;
				}
				int registeredCount = mSpenSignatureVerification
						.getRegisteredCount();
				mResult = registeredCount;
				txtCount.setText("Registration - (" + mResult + "/"
						+ mSignatureRegistrationNumMax + ")");
				if (mResult == mSignatureRegistrationNumMax) {
					Toast.makeText(mContext,
							"Signature registration is completed",
							Toast.LENGTH_SHORT).show();
					saveSignature();
				} else if (mResult > 0) {
					mSignatureRegistrationNum = mResult;
					Toast.makeText(mContext, "Signature has been stored.",
							Toast.LENGTH_SHORT).show();
				} else {
					Toast.makeText(
							mContext,
							"This signature is invalid for registration\n"
									+ "Please try again!", Toast.LENGTH_SHORT)
							.show();
				}

				for (SpenObjectBase obj : mSpenPageDoc.getObjectList()) {
					if (obj.getType() == SpenObjectBase.TYPE_STROKE)
						mSpenPageDoc.removeObject(obj);
				}
				mSpenSurfaceView.update();
			}
			return false;
		}
	};

	OnTouchListener imgClearTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			closeSettingView();
			for (SpenObjectBase obj : mSpenPageDoc.getObjectList()) {
				if (obj.getType() == SpenObjectBase.TYPE_STROKE)
					mSpenPageDoc.removeObject(obj);
			}
			mSpenSurfaceView.update();
			return false;
		}
	};

	OnTouchListener imgCheckTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			closeSettingView();
			ArrayList<SpenObjectBase> strokeList = mSpenPageDoc
					.getObjectList(SpenObjectBase.TYPE_STROKE);
			if (strokeList.size() > 0) {
				ArrayList<SpenObjectStroke> list = new ArrayList<SpenObjectStroke>();
				for (int i = 0; i < strokeList.size(); i++) {
					list.add((SpenObjectStroke) strokeList.get(i));
				}

				try {
					mSpenSignatureVerification.request(list);
				} catch (IllegalStateException e) {
					e.printStackTrace();
					Toast.makeText(mContext,
							"SpenSignatureVerification is not loaded.",
							Toast.LENGTH_SHORT).show();
					return false;
				} catch (Exception e) {
					e.printStackTrace();
					Toast.makeText(mContext,
							"SpenSignatureVerification is not loaded.",
							Toast.LENGTH_SHORT).show();
					return false;
				}
			}
			return false;
		}
	};
	
	OnTouchListener imgHelpTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			closeSettingView();
			File filePath = new File(getExternalCacheDir()
					.getAbsolutePath() + "/Delicious Hunter/SPD/Signature/");
			if (!filePath.exists()) {
				if (!filePath.mkdirs()) {
					Toast.makeText(mContext, "Save Path Creation Error",
							Toast.LENGTH_SHORT).show();
					return false;
				}
			}

			String saveFilePath = filePath.getPath() + '/';
			String fileName = "signature.spd";
			saveFilePath += fileName;
			File file = new File(saveFilePath);
			if(file.exists()){
				mSpenPageDoc.removeAllObject();
				loadNoteFile(saveFilePath);
			}
			
			return false;
		}
	};
	
	private void saveSignature(){
		File filePath = new File(getExternalCacheDir()
				.getAbsolutePath() + "/Delicious Hunter/SPD/Signature/");
		if (!filePath.exists()) {
			if (!filePath.mkdirs()) {
				Toast.makeText(mContext, "Save Path Creation Error",
						Toast.LENGTH_SHORT).show();
				return;
			}
		}

		String saveFilePath = filePath.getPath() + '/';
		String fileName = "signature.spd";
		saveFilePath += fileName;
		saveNoteFile(saveFilePath);
	}
	
	private void saveNoteFile(String strFileName) {
		try {
			mSpenNoteDoc.save(strFileName);
		} catch (IOException e) {
			Toast.makeText(mContext, "Cannot save NoteDoc file.",
					Toast.LENGTH_SHORT).show();
			e.printStackTrace();
			return;
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		return;
	}
	
	private void loadNoteFile(String filePath) {
		try {
			SpenNoteDoc tmpSpenNoteDoc = new SpenNoteDoc(mContext, filePath,
					600, SpenNoteDoc.MODE_WRITABLE);
			mSpenNoteDoc.close();
			mSpenNoteDoc = tmpSpenNoteDoc;
			if (mSpenNoteDoc.getPageCount() == 0) {
				mSpenPageDoc = mSpenNoteDoc.appendPage();
			} else {
				mSpenPageDoc = mSpenNoteDoc.getPage(0);
			}
			mSpenSurfaceView.setPageDoc(mSpenPageDoc, true);

		} catch (IOException e) {
			Toast.makeText(mContext, "Cannot open this file.",
					Toast.LENGTH_LONG).show();
		} catch (SpenUnsupportedTypeException e) {
			Toast.makeText(mContext, "This file is not supported.",
					Toast.LENGTH_LONG).show();
		} catch (SpenInvalidPasswordException e) {
			Toast.makeText(mContext, "This file is locked by a password.",
					Toast.LENGTH_LONG).show();
		} catch (SpenUnsupportedVersionException e) {
			Toast.makeText(mContext,
					"This file is the version that does not support.",
					Toast.LENGTH_LONG).show();
		} catch (Exception e) {
			Toast.makeText(mContext, "Failed to load noteDoc.",
					Toast.LENGTH_LONG).show();
		}
	}

	private void closeSettingView() {
	}

	// OnDestroy
	@Override
	protected void onDestroy() {
		super.onDestroy();
		clearObject();
	}

	private void clearObject() {
		if (mSpenSignatureVerification != null) {
			mSpenSignatureVerificationManager
					.destroySignatureVerification(mSpenSignatureVerification);
			mSpenSignatureVerificationManager.close();
		}

		if (mSpenSurfaceView != null) {
			mSpenSurfaceView.close();
			mSpenSurfaceView = null;
		}

		if (mSpenNoteDoc != null) {
			try {
				mSpenNoteDoc.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			mSpenNoteDoc = null;
		}
	}

	@Override
	public void onBackPressed() {
		if (mResult != mSignatureRegistrationNumMax)
			Toast.makeText(
					mContext,
					"You have to register a new signature" + "\n"
							+ " or authentication", Toast.LENGTH_SHORT).show();
		else {
			super.onBackPressed();
		}
	}

}